package com.dateConstruction._05_genList;

// 广义表操作类
public class GenLists {
    
    // 静态成员变量
    private static int i = 0;
    
    // 返回以gliststr表示创建的广义表，gliststr语法正确，不是null、空串""
    public static GenList<String> create(String gliststr) {
        i = 0;
        // 构造树，没有共享子表
        // 创建子表，null是对开头的处理，因为还没得到表名data
        return createsub(gliststr, null);
    }
    
    /*
    
    G(d, L(a, b), T(c, L(a, b)))观察这么一个广义表，我们可以得到以下信息：
    '('前面的原子一定是该括号内子表的表名，'('意味着需要创建一个新的子表，')'则意味着该子表没有原子需要创建了，那么该子表创建结束，return 该子表
    ','则直接跳过意味着需要创建下一个原子
    
     */
    // 返回从gliststr[i]开始的子串创建的子广义表，data指定表名；原子和表名都是字符串，递归方法。
    // 不能创建共享子表。由于i从0开始线性递增，所有递归方法公用一个i，因此只能声明i是成员变量，不是局部变量。
    private static GenList<String> createsub(String gliststr, String data) {
        // TODO Auto-generated method stub
        if (data == null) {
            // 返回指定字符在串中的位置
            i = gliststr.indexOf('(');
            // '('前的字符串是表名
            data = gliststr.substring(0, i);
        }
        // 构造空串，data指定表名
        GenList<String> genlist = new GenList<String>(data);
        // 指向头结点
        GenNode<String> p = genlist.head;
        // 跳过'('
        i++;
        while (i < gliststr.length()) {
            switch (gliststr.charAt(i)) {
                case ',': i++; break;
                case ')': i++; return genlist;
                default :
                    // 字符
                    // 以下循环从第i个字符开始寻找原子/表名子串，以'('或')'之一作为分割符
                    int end = i;
                    while (end < gliststr.length() && "(,)".indexOf(gliststr.charAt(end)) == -1) {
                        end++;
                    }
                    // i ~ end-1的子串是原子/表名
                    data = gliststr.substring(i, end);
                    // 改变i到下个分割符的位置
                    i = end;
                    // 创建原子/子表结点；子表结点有表名，无表名时为空串
                    p.next = new GenNode<String>(data, null, null);
                    p = p.next;
                    if (i < gliststr.length() && gliststr.charAt(i) == '(') {
                        // 创建子表，递归调用
                        p.child = createsub(gliststr, data);
                    }
                    
            }
        }
        return genlist;
    }
    
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String gliststr0 = "G(d, L(a,b), T(c, L(a, b)))";
        GenList<String> graph0 = GenLists.create(gliststr0);
        System.out.println(graph0.toString());
        String gliststr1 = "(d, L(a, b), T(c, L(a, b)))";
        GenList<String> graph1 = GenLists.create(gliststr1);
        System.out.println(graph1.toString());
        
    }

    

}
